package com.mjkj.demo.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mjkj.demo.annotation.DataSource;
import com.mjkj.demo.constant.Constants;
import com.mjkj.demo.core.exception.ServiceException;
import com.mjkj.demo.core.redis.RedisCache;
import com.mjkj.demo.core.result.Result;
import com.mjkj.demo.core.result.ResultGenerator;
import com.mjkj.demo.enums.DataSourceType;
import com.mjkj.demo.mapper.UserMapper;
import com.mjkj.demo.model.entity.Users;
import com.mjkj.demo.model.req.LoginReq;
import com.mjkj.demo.model.req.UserReq;
import com.mjkj.demo.model.vo.LoginVo;
import com.mjkj.demo.model.vo.UserVo;
import com.mjkj.demo.service.UserService;
import com.mjkj.demo.utils.MD5Utils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static com.mjkj.demo.core.exception.ErrorCodeConstants.USERNAME_OR_PASSWORD_ERROR;

/**
 * @author XuDoom
 * @version 1.0
 * @date 2023/11/30 14:57
 */
@Service
@DataSource(value = DataSourceType.MASTER)
public class UserServiceImpl extends ServiceImpl<UserMapper, Users> implements UserService {

    @Resource
    UserMapper userMapper;

    private static final String ADMIN = "admin";

    private static final String PASSWORD = "123456";

    @Resource
    RedisCache redisCache;

    @Override
    public Result<LoginVo> login(LoginReq loginReq) {
        // 验证用户
        Users users = authenticate(loginReq.getUsername(), loginReq.getPassword());
        if (loginReq.getType() == 1 && !ADMIN.equals(users.getRole())){
            throw new ServiceException(201, "此账号无法登陆后台管理系统！！！");
        }
        //执行登陆方法
        StpUtil.login(users.getId());
        // 放入redis
        redisCache.setCacheObject(Constants.REDIS_LOGIN_ROLE_CODE_KEY + ":" + users.getId(), users.getRole());
        // 生成响应数据
        LoginVo res = new LoginVo();
        res.setToken(StpUtil.getTokenValue());
        res.setRole(users.getRole());
        return ResultGenerator.genSuccessResult(res);
    }

    @Override
    public List<UserVo> listUser() {
        List<Users> list = list();
        return list.stream().map(e->{
            UserVo userVo = new UserVo();
            userVo.setId(e.getId());
            userVo.setUsername(e.getUsername());
            userVo.setRole(e.getRole());
            return userVo;
        }).collect(Collectors.toList());
    }

    @Override
    public void addUser(UserReq userReq) {

        Users users1 = userMapper.selectByUsername(userReq.getUsername());
        if (users1 != null) {
            throw new ServiceException(201, "用户名重复");
        }

        Users users = new Users();
        users.setUsername(userReq.getUsername());
        users.setPassword(MD5Utils.convertMD5(MD5Utils.md5(PASSWORD)));
        users.setRole(userReq.getRole());
        save(users);
    }

    @Override
    public void updateUser(UserReq userReq) {
        Integer id = userReq.getId();
        Users users1 = getById(id);
        if (users1 == null) {
            throw new ServiceException(201, "id无效");
        }
        Users users = new Users();
        users.setId(userReq.getId());
        users.setUsername(userReq.getUsername());
        users.setRole(userReq.getRole());
        updateById(users);

    }

    public Users authenticate(String username, String password) {
        Users users = getUserByUsername(username);
        if (users == null){
            throw new ServiceException(USERNAME_OR_PASSWORD_ERROR);
        }
        if (isPasswordNotMatch(password, users.getPassword())) {
            throw new ServiceException(USERNAME_OR_PASSWORD_ERROR);
        }
        return users;
    }

    public Users getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }


    public boolean isPasswordMatch(String rawPassword, String encodedPassword) {
        return encodedPassword.equals(MD5Utils.convertMD5(MD5Utils.md5(rawPassword)));
    }
    public boolean isPasswordNotMatch(String rawPassword, String encodedPassword) {
        return !isPasswordMatch(rawPassword, encodedPassword);
    }
}
